﻿using System;
using WikiPlex.Formatting;

namespace WikiMaml.Renderers
{
    /// <summary>
    /// Handles rendering of the various topics.
    /// </summary>
    public class TopicRenderer : IRenderer
    {
        private const string OpenTagFormat = @"<?xml version=""1.0"" encoding=""utf-8""?><topic id=""{0}"" revisionNumber=""1""><{1} xmlns=""http://ddue.schemas.microsoft.com/authoring/2003/5"" xmlns:xlink=""http://www.w3.org/1999/xlink"">";
        private const string CloseTagFormat = @"</{0}></topic>";
        private const string ConceptualTagName = "developerConceptualDocument";
        private const string WalkthroughTagName = "developerWalkthroughDocument";

        /// <summary>
        /// Gets the id of a renderer.
        /// </summary>
        public string Id
        {
            get { return "Topic"; }
        }

        /// <summary>
        /// Determines if this renderer can expand the given scope name.
        /// </summary>
        /// <param name="scopeName">The scope name to check.</param>
        /// <returns>
        /// A boolean value indicating if the renderer can or cannot expand the macro.
        /// </returns>
        public bool CanExpand(string scopeName)
        {
            return (scopeName == MamlScopeName.ConceptualTopicBegin
                    || scopeName == MamlScopeName.ConceptualTopicEnd
                    || scopeName == MamlScopeName.WalkthroughTopicBegin
                    || scopeName == MamlScopeName.WalkthroughTopicEnd) ;
        }

        /// <summary>
        /// Will expand the input into the appropriate content based on scope.
        /// </summary>
        /// <param name="scopeName">The scope name.</param>
        /// <param name="input">The input to be expanded.</param>
        /// <param name="htmlEncode">Function that will html encode the output.</param>
        /// <param name="attributeEncode">Function that will html attribute encode the output.</param>
        /// <returns>
        /// The expanded content.
        /// </returns>
        public string Expand(string scopeName, string input, Func<string, string> htmlEncode, Func<string, string> attributeEncode)
        {
            switch (scopeName)
            {
                case MamlScopeName.ConceptualTopicBegin:
                    return string.Format(OpenTagFormat, attributeEncode(input), ConceptualTagName);
                case MamlScopeName.ConceptualTopicEnd:
                    return string.Format(CloseTagFormat, ConceptualTagName);
                case MamlScopeName.WalkthroughTopicBegin:
                    return string.Format(OpenTagFormat, attributeEncode(input), WalkthroughTagName);
                case MamlScopeName.WalkthroughTopicEnd:
                    return string.Format(CloseTagFormat, WalkthroughTagName);
                default:
                    return input;
            }
        }
    }
}
